package net.cattaka.allcom.android;

import java.io.IOException;
import java.util.List;

import org.apache.http.client.HttpResponseException;

import net.cattaka.allcom.android.entity.Card;
import net.cattaka.allcom.android.net.ServerInterface;
import net.cattaka.allcom.android.util.PreferenceUtil;

import com.felicanetworks.mfc.AppInfo;
import com.felicanetworks.mfc.Felica;
import com.felicanetworks.mfc.FelicaEventListener;
import com.felicanetworks.mfc.FelicaException;
import com.felicanetworks.mfc.PushIntentSegment;
import com.felicanetworks.mfc.PushSegment;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

/**
 * FeliCaで情報を受け取った時にIntent経由で起動するActivity.
 * 
 * 送信相手のトークンを受け取り、WEBサーバーに問い合せて取得した
 * 自己紹介を表示する
 * 
 * @author keiji_ariyama
 *
 */
public class CardActivity extends Activity implements OnClickListener {
    public static final boolean DEBUG_FLG = true;
    public static final String TAG = "CardActivity";

    //** Felicaサービスと接続して、activateが完了した */
    private static final int HANDLE_FELICA_IS_READY = 0x01;

    //** Felicaサービスをinactivateして、サービスとの接続が解除された */
    private static final int HANDLE_FELICA_IS_INACTIVATED = 0x02;
    
    private final Handler mHandler = new Handler() {
        public void dispatchMessage(android.os.Message msg) {
            switch(msg.what) {
                case HANDLE_FELICA_IS_READY :
                    if(DEBUG_FLG)  Log.d(TAG, "FeliCa Is Ready.");
                    break;
                case HANDLE_FELICA_IS_INACTIVATED :
                    if(DEBUG_FLG)  Log.d(TAG, "Service unbind");
                    break;
            }
        }
    };

    private boolean mConnected = false;
    private Felica mFelica = null;

    private ListView mListView = null;
    private class Adapter extends BaseAdapter {

        private List<Card> mList = null;
        public void setList(List<Card> list) {
            mList = list;
        }
        
        @Override
        public int getCount() {
            if( mList != null ) return mList.size();
            return 0;
        }

        @Override
        public Object getItem(int position) {
            return mList.get(position);
        }

        @Override
        public long getItemId(int position) {
            Card card = (Card) mList.get(position);
            return card.getId();
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = View.inflate(getApplicationContext(), R.layout.card_row, null);

            Card card = (Card)getItem(position);
            ((TextView)view.findViewById(R.id.num)).setText(String.valueOf(card.getId()));
            ((TextView)view.findViewById(R.id.name)).setText(String.valueOf(card.getName()));
            
            if(card.getKnown() == Card.KNOWN) ((TextView)view.findViewById(R.id.known)).setText(R.string.known);

                return view;
        }
        
    }
    /** FeliCaを初期化する際に使用する証明書文字列（nullを指定） */
    private static final String[] CERTS = null;

    /*
     * FeliCaサービスと接続するのコネクションインターフェース
     */
    private final ServiceConnection mFelicaConnection = new ServiceConnection() {

        /*
         * (non-Javadoc)
         * @see android.content.ServiceConnection#onServiceConnected(android.content.ComponentName, android.os.IBinder)
         */
        public void onServiceConnected(ComponentName name, IBinder service) {
            if(DEBUG_FLG)  Log.d(TAG, "onServiceConnected");

            // Felicaインスタンスを取得する
            mFelica = ((Felica.LocalBinder) service).getInstance();
            mConnected = true;
            
            if(mFelica == null) {
                Toast.makeText(getApplicationContext(), "Cannot  obtained a Felica object",  Toast.LENGTH_SHORT).show();
                
            } else {
                try {
                    mFelica.activateFelica(CERTS, mFelicaEventListener);
                } catch (IllegalArgumentException e) {
                    Log.e(TAG, "IllegalArgumentException", e);
                } catch (FelicaException e) {
                    Toast.makeText(getApplicationContext(), "Felica cannot activate.",  Toast.LENGTH_SHORT).show();
                }
            }
        }

        /*
         * (non-Javadoc)
         * @see android.content.ServiceConnection#onServiceDisconnected(android.content.ComponentName)
         */
        public void onServiceDisconnected(ComponentName name) {
            if(DEBUG_FLG)  Log.d(TAG, "onServiceDisconnected");

            mFelica = null;
            
            // Felicaの設定解除
            mConnected = false;
            
            mHandler.sendEmptyMessage(HANDLE_FELICA_IS_INACTIVATED);
        }

    };

    // FeliCaのactivateの状態を受け取るリスナー
    private final FelicaEventListener mFelicaEventListener = new FelicaEventListener() {

        /*
         * (non-Javadoc)
         * @see com.felicanetworks.mfc.FelicaEventListener#finished()
         */
        public void finished() {
            try {
                mFelica.open();
            } catch (FelicaException e) {
                Toast.makeText(getApplicationContext(), "Felica cannot open.",  Toast.LENGTH_SHORT).show();
            }
            
            mHandler.sendEmptyMessage(HANDLE_FELICA_IS_READY);
        }

        /*
         * (non-Javadoc)
         * @see com.felicanetworks.mfc.FelicamFelicaEventListenerEventListener#errorOccurred(int, java.lang.String, com.felicanetworks.mfc.AppInfo)
         */
        public void errorOccurred(int id, String msg, AppInfo otherAppInfo) {

            String result = "Felica#activateFelica() failed\nError:";

            switch (id) {
                case FelicaEventListener.TYPE_USED_BY_OTHER_APP:
                    // 他アプリケーションによってFeliCaチップが使用中の場合
                    result += "FeliCa Chip is used by other application(PID:" + otherAppInfo.getPid()
                            + ")";
                    break;
                case FelicaEventListener.TYPE_NOT_FOUND_ERROR:
                    // 利用可能な許可証がみつからなかった場合
                    result += "valid permits not found";
                    break;
                case FelicaEventListener.TYPE_HTTP_ERROR:
                    // 許可証検証中にHTTPエラーが発生した場合
                    result += "HTTP error";
                    break;
                case FelicaEventListener.TYPE_MFC_VERSION_ERROR:
                    // MFCのバージョンアップが必要な場合
                    result += "MFC version is too old";
                    break;
                case FelicaEventListener.TYPE_UTILITY_VERSION_ERROR:
                    // MFCユーティリティのバージョンアップが必要な場合
                    result += "MFC utility version is too old";
                    break;
                case FelicaEventListener.TYPE_UNKNOWN_ERROR:
                    // その他のエラー
                    result += "unknown error";
                    break;
                default:
                    // MFC仕様上、想定外のパス
                    result += "nexpected error";
                    break;
            }
            if (msg != null) {
                result += "\nerror detail:" + msg;
            }

            if(DEBUG_FLG) Log.e(TAG, result);
        }
    };

    private PreferenceUtil mPreferenceUtil = null;

    private String mTargetId = null;
    public static final String KEY_ID = "ID";

    private String mId = null;

    /*
     * (non-Javadoc)
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        mPreferenceUtil = new PreferenceUtil(getApplicationContext());
        
        mId = mPreferenceUtil.getId();
        
        mTargetId = getIntent().getStringExtra(KEY_ID);
        if(mTargetId == null) {
           Log.e(TAG, "target id = null");
        }
        
        setContentView(R.layout.card);

        findViewById(R.id.button).setOnClickListener(this);
        mListView = (ListView)findViewById(R.id.com_list);
        mAdapter = new Adapter();
        
        List<Card> list = null;
        try {
            list = ServerInterface.getCardList(mId, mTargetId);
        } catch (HttpResponseException e) {
            Log.e(TAG, "HttpResponseException", e);
        } catch (IOException e) {
            Log.e(TAG, "IOException", e);
        }
        
        if(list != null) {
            if(DEBUG_FLG) Log.d(TAG, "list length = " + list.size());
            
            mAdapter.setList(list);
            mListView.setAdapter(mAdapter);
        }
    }

    private Adapter mAdapter = null;
    
    /*
     * (non-Javadoc)
     * @see android.app.Activity#onResume()
     */
    @Override
    protected void onResume() {
        super.onResume();
    
        connectFelicaService();

    }
    
    /*
     * (non-Javadoc)
     * @see android.app.Activity#onPause()
     */
    @Override
    protected void onPause() {
        super.onPause();

        disconnectFelicaService();
        
        if(DEBUG_FLG)  Log.d(TAG, "id = " + mPreferenceUtil.getId());

    }
    
    /**
     * 接続
     */
    private void connectFelicaService() {
        if(DEBUG_FLG)  Log.d(TAG, "connectFelicaService");

        Intent intent = new Intent();
        intent.setClass(getApplicationContext(), Felica.class);
        if (!bindService(intent, mFelicaConnection,
                Context.BIND_AUTO_CREATE)) {

            return;
        }
    }

    /**
     * 切断
     */
    private void disconnectFelicaService() {
        if(DEBUG_FLG)  Log.d(TAG, "disconnectFelicaService");
        unbindService(mFelicaConnection);
    }

    /*
     * (non-Javadoc)
     * @see android.view.View.OnClickListener#onClick(android.view.View)
     */
    @Override
    public void onClick(View v) {
        switch(v.getId()) {
            case R.id.button :
                Intent intent = new Intent(this, CardActivity.class);
                intent.putExtra("id", mId);
                
                PushSegment ps = new PushIntentSegment(intent);
                
                try {
                    mFelica.open();
                    mFelica.push(ps);
                    mFelica.close();
                } catch (IllegalArgumentException e) {
                    Toast.makeText(getApplicationContext(), "IllegalArgumentException",  Toast.LENGTH_SHORT).show();
                } catch (FelicaException e) {
                    Toast.makeText(getApplicationContext(), "FelicaException",  Toast.LENGTH_SHORT).show();
                }
                
                break;
        }
    }    
}
